<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1256">
	<TITLE></TITLE>
	<META NAME="GENERATOR" CONTENT="OpenOffice.org 3.3  (Win32)">
	<META NAME="CREATED" CONTENT="20121220;6460838">
	<META NAME="CHANGEDBY" CONTENT="Najim BOUJEDLI">
	<META NAME="CHANGED" CONTENT="20121221;7263593">
	<SCRIPT></SCRIPT>
	<SCRIPT LANGUAGE="javascript" SRC="/B1D671CF-E532-4481-99AA-19F420D90332/netdefender/hui/ndhui.js%3F0=0&amp;0=0&amp;0=0"></SCRIPT>
	<STYLE TYPE="text/css">
	<!--
		@page { size: 21.01cm 29.69cm; margin: 2.01cm }
		P { margin-bottom: 0.2cm }
		PRE.western { font-family: "Courier New", monospace }
		PRE.cjk { font-family: "NSimSun", monospace }
		PRE.ctl { font-family: "Courier New", monospace }
		A:link { so-language: zxx }
	-->
	</STYLE>
</HEAD>
<BODY LANG="fr-FR" DIR="LTR">
<P ALIGN=CENTER STYLE="margin-bottom: 0cm"><FONT SIZE=5 STYLE="font-size: 20pt"><B>projet
Informatique Graphique</B></FONT></P>
<P ALIGN=CENTER STYLE="margin-bottom: 0cm"><FONT SIZE=5 STYLE="font-size: 20pt">Pacman</FONT></P>
<P STYLE="margin-bottom: 0cm">Membre du projet : PEREZ Julien et
Najim Boujedli</P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<P ALIGN=CENTER STYLE="margin-bottom: 0cm"><FONT SIZE=4><B>contr&ocirc;les
de l'application</B></FONT></P>
<UL>
	<LI><P ALIGN=LEFT STYLE="margin-bottom: 0cm">global</P>
</UL>
<UL>
	<P STYLE="margin-bottom: 0cm">+ =&gt; augmentation de la vitesse 
	</P>
	<P STYLE="margin-bottom: 0cm">- =&gt; diminution de la vitesse</P>
	<P STYLE="margin-bottom: 0cm">r =&gt; recommencer lors d'un game
	over</P>
</UL>
<P STYLE="margin-bottom: 0cm">:</P>
<UL>
	<LI><P STYLE="margin-bottom: 0cm">Fen&ecirc;tre une</P>
</UL>
<P STYLE="margin-bottom: 0cm">drag and drop avec clic gauche =&gt;
rotation de la sc&egrave;ne</P>
<P STYLE="margin-bottom: 0cm">drag and drop avec clic central =&gt;
zoom ou d&eacute;zoom de la sc&egrave;ne</P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<P ALIGN=CENTER STYLE="margin-bottom: 0cm"><FONT SIZE=4><B>d&eacute;tails
techniques</B></FONT></P>
<P STYLE="margin-bottom: 0cm"><FONT SIZE=4><U><B>Structure globale</B></U></FONT></P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<P STYLE="margin-bottom: 0cm">Pour r&eacute;aliser ce projet, une
approche par la programmation orient&eacute;e objet a &eacute;t&eacute;
effectu&eacute;e.</P>
<P STYLE="margin-bottom: 0cm">En effet la POO permet de fractionner
plus facilement le programme en le rendant plus lisible mais aussi de
mieux <EM><SPAN STYLE="font-style: normal">partitionner</SPAN></EM>
le travail de chacun &agrave; l'int&eacute;rieur de chacune des
classes.</P>
<P STYLE="margin-bottom: 0cm">Pour ce faire, on a cr&eacute;&eacute;
une classe pour chaque composant graphique :</P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<UL>
	<LI><P STYLE="margin-bottom: 0cm">Scene est la classe centrale de
	l'application: 
	</P>
</UL>
<P STYLE="margin-bottom: 0cm">C'est elle qui va g&eacute;rer &agrave;
la fois certaines collisions (Pacman/boules Pacman/fant&ocirc;me), la
cr&eacute;ation de tout les autres &eacute;l&eacute;ments graphiques,
puis leurs affichages ainsi que la gestion des cameras et le
d&eacute;placement de tout les personnages.</P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<P STYLE="margin-bottom: 0cm">Pour cela elle contient un Vector de
Character, Collectable ainsi qu'un Field.</P>
<UL>
	<LI><P STYLE="margin-bottom: 0cm">Field repr&eacute;sente le terrain
	en lui m&ecirc;me:</P>
</UL>
<P STYLE="margin-bottom: 0cm">Afin de faciliter la gestion des
d&eacute;placements et du placement des diff&eacute;rents &eacute;l&eacute;ments
on a consid&eacute;r&eacute; que le terrain pouvait se sch&eacute;matiser
en une grille o&ugrave; chaque case pouvait poss&eacute;der l'un des
&eacute;l&eacute;ments suivants : un fant&ocirc;me, un Pacman, une
boule jaune, une boule rouge(appel&eacute;e &laquo;&nbsp;Destructor&nbsp;&raquo;),
un mur classique ou un mur invisible (appel&eacute; &laquo;&nbsp;twistedWall&nbsp;&raquo;)
.</P>
<P STYLE="margin-bottom: 0cm">Cette grille est par la suite utilis&eacute;e
pour d&eacute;terminer les &eacute;ventuelles collisions entre les
&eacute;l&eacute;ments (sauf la collision Pacman fant&ocirc;me qui
est r&eacute;alis&eacute;e diff&eacute;remment) ainsi que l'affichage
des murs.</P>
<P STYLE="margin-bottom: 0cm">Cette m&ecirc;me classe contient
l'ensemble des murs dans un vector de Wall.</P>
<UL>
	<LI><P STYLE="margin-bottom: 0cm">Wall repr&eacute;sente un mur sur
	une case unique :</P>
</UL>
<P STYLE="margin-bottom: 0cm">On peut dessiner au final cinq types de
murs dans le jeu.</P>
<P STYLE="margin-bottom: 0cm">Cette classe regroupe donc cinq
m&eacute;thodes pour afficher les cinq types de murs diff&eacute;rents.</P>
<P STYLE="margin-bottom: 0cm">La cat&eacute;gorie de mur est
directement d&eacute;termin&eacute;e lors de la cr&eacute;ation du
mur. Pour r&eacute;aliser ceci, on regarde la pr&eacute;sence ou non
de mur dans les quatre cases diagonales du mur trait&eacute;.</P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<UL>
	<LI><P STYLE="margin-bottom: 0cm">Collectable est une classe
	virtuelle pure qui repr&eacute;sente un objet pouvant &ecirc;tre
	ramass&eacute; au cours d'une partie.</P>
</UL>
<P STYLE="margin-bottom: 0cm">C'est la classe m&egrave;re de Ball et
Destructor.</P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<UL>
	<LI><P STYLE="margin-bottom: 0cm">Ball est associ&eacute; aux boules
	jaunes pr&eacute;sente sur une grande partie de la carte.</P>
</UL>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<UL>
	<LI><P STYLE="margin-bottom: 0cm">Destructor est identique &agrave;
	la classe Ball &agrave; ceci pr&ecirc;t que les boules affich&eacute;es
	sont rouges.</P>
</UL>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<UL>
	<LI><P STYLE="margin-bottom: 0cm">Character repr&eacute;sente un
	&eacute;l&eacute;ment pouvant se d&eacute;placer avec un certain
	but.</P>
</UL>
<P STYLE="margin-bottom: 0cm">C'est une classe virtuelle pure mais
aussi la classe m&egrave;re de Pacman et Ghost.</P>
<P STYLE="margin-bottom: 0cm">Elle contient par ailleurs une bonne
partie des attributs communs &agrave; ces deux classes(width,
positionX etc...).</P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<UL>
	<LI><P STYLE="margin-bottom: 0cm">Pacman repr&eacute;sente notre
	grosse boule jaune qui se d&eacute;place.</P>
</UL>
<P STYLE="margin-bottom: 0cm">Cette classe contient toutes les
informations relatives au positionnement de notre Pacman sur la sc&egrave;ne
(position en X, Z et l'angle par rapport &agrave; Y).</P>
<P STYLE="margin-bottom: 0cm">Elle contient aussi la position du
prochain mouvement demand&eacute; par le joueur.</P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<UL>
	<LI><P STYLE="margin-bottom: 0cm">Ghost repr&eacute;sente nos
	impitoyables ennemis.</P>
</UL>
<P STYLE="margin-bottom: 0cm">Elle contient l'ensemble des
informations relatives &agrave; un fant&ocirc;me.</P>
<P STYLE="margin-bottom: 0cm">Mais &agrave; contrario de Pacman, elle
g&egrave;re toute seule son comportement sur la carte.</P>
<P STYLE="margin-bottom: 0cm">Pour cela une variable de type enti&egrave;re
nomm&eacute;e &laquo;&nbsp;comportement&nbsp;&raquo; est pr&eacute;sente
pour indiquer quel type de d&eacute;placement le fant&ocirc;me doit
adopter &agrave; un instant t.</P>
<P STYLE="margin-bottom: 0cm">En fonction des diff&eacute;rents
comportements, l'affichage est modifi&eacute; en cons&eacute;quence.</P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<P STYLE="margin-bottom: 0cm">Une derni&egrave;re classe est pr&eacute;sente
dans le logiciel mais n'est pas contenue dans Scene : la classe
Player.</P>
<P STYLE="margin-bottom: 0cm">Cette classe regroupe simplement
quelques variables utiles pour le joueur : le score, le nombre de vie
ainsi que le niveau actuel. 
</P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<P STYLE="margin-bottom: 0cm; font-style: normal"><FONT SIZE=4><U><B>Cr&eacute;ation
de la sc&egrave;ne</B></U></FONT></P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<P STYLE="margin-bottom: 0cm">Lors de la cr&eacute;ation de ce
logiciel nous avons essay&eacute; de rendre la cr&eacute;ation des
sc&egrave;nes le plus modulable possible afin de pouvoir modifier les
sc&egrave;nes ais&eacute;ment.</P>
<P STYLE="margin-bottom: 0cm">Toute l'op&eacute;ration de cr&eacute;ation
des divers composants graphiques se r&eacute;alise dans le
constructeur de la classe Scene.</P>
<P STYLE="margin-bottom: 0cm">Ce proc&eacute;d&eacute; permet de
pouvoir recr&eacute;er la sc&egrave;ne facilement et ce &agrave;
n'importe quel moment : c'est d'ailleurs ce qui se passe dans le cas
d'un game over, la sc&egrave;ne est enti&egrave;rement d&eacute;truite
puis reconstruite juste derri&egrave;re.</P>
<P STYLE="margin-bottom: 0cm">Tout les composants graphiques
poss&egrave;dent un maximum de param&egrave;tre dans leurs
constructeurs ce qui les rend plus modulables.</P>
<P STYLE="margin-bottom: 0cm">La cr&eacute;ation du terrain contient
comme argument par exemple : la largeur de la carte, la hauteur, les
cordonn&eacute;es minimales et maximales de la zone de repopulation
ainsi que les coordonn&eacute;es du point pour en sortir.</P>
<P STYLE="margin-bottom: 0cm">La cr&eacute;ation des murs se fait
dans la m&eacute;thode <I>buildMap</I> de la classe Field.</P>
<P STYLE="margin-bottom: 0cm">Dans cette m&eacute;thode la grille est
remplie gr&acirc;ce aux m&eacute;thodes <I>drawVLineWall</I> et
<I>drawHLineWall</I> qui tracent des lignes verticales et
horizontales de murs aux coordonn&eacute;es indiqu&eacute;es.</P>
<P STYLE="margin-bottom: 0cm">Cette technique &agrave; l'avantage
d'&ecirc;tre facilement modifiable mais n'est pas forcement tr&egrave;s
esth&eacute;tique.</P>
<P STYLE="margin-bottom: 0cm">La cr&eacute;ation des boules jaunes se
fait diff&eacute;remment.</P>
<P STYLE="margin-bottom: 0cm">Dans la classe Scene la m&eacute;thode
<FONT COLOR="#0000ff"><I>void</I></FONT> <I>placeItems( </I><FONT COLOR="#0000ff"><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>int</I></FONT></FONT></FONT>
<I>x, </I><FONT COLOR="#0000ff"><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>int</I></FONT></FONT></FONT>
<I>z)</I> permet d'effectuer cette op&eacute;ration.</P>
<P STYLE="margin-bottom: 0cm">X et Z sont les coordonn&eacute;es
d'une case libre sur la grille.</P>
<P STYLE="margin-bottom: 0cm">A partir de cette coordonn&eacute;e on
va r&eacute;p&eacute;ter r&eacute;cursivement l'algorithme sur les
cases libres pr&eacute;sentes aux quatre points cardinaux de la case
trait&eacute;e jusqu'&agrave; ce que l'algorithme ne trouve plus de
place o&ugrave; cr&eacute;er de nouvelles boules jaunes.</P>
<P STYLE="margin-bottom: 0cm">Suite &agrave; ceci on trie notre
vector o&ugrave; sont stock&eacute;es toutes nos boules gr&acirc;ce &agrave;
l'algorithme du tri Bulle afin d'obtenir un vector rang&eacute; par
ordre croissant selon leurs coordonn&eacute;es X puis leurs
coordonn&eacute;es Z.</P>
<P STYLE="margin-bottom: 0cm">Ce rangement est indispensable par la
suite lors de la gestion des collisions Pacman / Collectable.</P>
<P STYLE="margin-bottom: 0cm">Dans le cas o&ugrave; on voudrait cr&eacute;er
des zones sans boules jaunes sur la carte l<FONT FACE="Times New Roman, serif">a</FONT>
<FONT FACE="Times New Roman, serif"><FONT SIZE=3>fonction </FONT></FONT><FONT COLOR="#0000ff"><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>void</I></FONT></FONT></FONT>
<FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>removeSquareballs(</I></FONT></FONT><FONT COLOR="#0000ff"><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>int</I></FONT></FONT></FONT><FONT COLOR="#000000">
</FONT><FONT COLOR="#000000"><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>x1,
</I></FONT></FONT></FONT><FONT COLOR="#0000ff"><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>int</I></FONT></FONT></FONT><FONT COLOR="#000000">
</FONT><FONT COLOR="#000000"><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>z1,
</I></FONT></FONT></FONT><FONT COLOR="#0000ff"><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>int</I></FONT></FONT></FONT><FONT COLOR="#000000">
</FONT><FONT COLOR="#000000"><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>x2,
</I></FONT></FONT></FONT><FONT COLOR="#0000ff"><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>int</I></FONT></FONT></FONT><FONT COLOR="#000000">
</FONT><FONT COLOR="#000000"><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>z2)</I></FONT></FONT></FONT><FONT COLOR="#000000">
</FONT><FONT COLOR="#000000"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>est
pr&eacute;sente.</FONT></FONT></FONT></P>
<P STYLE="margin-bottom: 0cm"><FONT COLOR="#000000"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>La
cr&eacute;ation des personnage se fait elle aussi dans la classe
Scene et plus particuli&egrave;rement dans la m&eacute;thode </FONT></FONT></FONT><FONT COLOR="#0000ff"><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>void</I></FONT></FONT></FONT><FONT COLOR="#000000">
</FONT><FONT COLOR="#000000"><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>createCharacters()</I></FONT></FONT></FONT><FONT COLOR="#000000">
</FONT><FONT COLOR="#000000"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>o&ugrave;
l'on se contente de remplir notre vector de Character avec de
nouvelles instances de Pacman et Ghost aux positions d&eacute;finies.</FONT></FONT></FONT></P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<P STYLE="margin-bottom: 0cm"><FONT SIZE=4><U><B>Gestion des
mouvements</B></U></FONT></P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<P STYLE="margin-bottom: 0cm"><U>Pacman :</U></P>
<P STYLE="margin-bottom: 0cm">La gestion du Pacman se fait gr&acirc;ce
aux contr&ocirc;les clavier et les m&eacute;thodes
<FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>glutSpecialFunc(specialKeyboard1)</I></FONT></FONT>
<FONT FACE="Times New Roman, serif"><FONT SIZE=3>pour l'&eacute;cran
o&ugrave; la camera est a&eacute;rienne et
</FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>glutSpecialFunc(specialKeyboard2)</I></FONT></FONT>
<FONT FACE="Times New Roman, serif"><FONT SIZE=3>pour l'&eacute;cran
o&ugrave; la camera est a la premi&egrave;re personne.</FONT></FONT></P>
<P STYLE="margin-bottom: 0cm"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>En
effet les contr&ocirc;les ne sont pas les m&ecirc;me selon que l'on
clique sur une fen&ecirc;tre ou sur l'autre.</FONT></FONT></P>
<P STYLE="margin-bottom: 0cm"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>Dans
la fen&ecirc;tre une, seule la position de la camera par rapport &agrave;
la sc&egrave;ne est pris en compte pour calculer le prochain
changement de direction.</FONT></FONT></P>
<P STYLE="margin-bottom: 0cm"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>Appuyer
sur la fl&egrave;che up demandera au Pacman de monter d&egrave;s que
cela sera possible donc si l'angle de la sc&egrave;ne est &eacute;gal
a z&eacute;ro alors il ira vers le haut si l'angle est &eacute;gal &agrave;
90&deg; alors il partira gauche etc...</FONT></FONT></P>
<P STYLE="margin-bottom: 0cm"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>Cela
se passe diff&eacute;remment pour la fen&ecirc;tre num&eacute;ro deux
ou le prochain mouvement enregistr&eacute; se calcule par rapport &agrave;
l'angle que poss&egrave;de le Pacman par rapport &agrave; la sc&egrave;ne.</FONT></FONT></P>
<P STYLE="margin-bottom: 0cm"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>De
ce fait si le Pacman poss&egrave;de un angle de z&eacute;ro degr&eacute;
(orient&eacute; vers le bas) alors appuyer sur la fl&egrave;che down
le fera allez vers le haut et appuyer sur la droite enregistrera la
prochaine direction gauche.</FONT></FONT></P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<P STYLE="margin-bottom: 0cm"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>Une
fois que le Pacman avance il ne s'arr&ecirc;te plus jusqu'&agrave;
rencontrer un mur ou que le d&eacute;placement demand&eacute; est
effectuable.</FONT></FONT></P>
<P STYLE="margin-bottom: 0cm"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>A
chaque frame le syst&egrave;me regarde si le Pacman est au milieu
d'une case c'est a dire si sa position en X et en Z ne poss&egrave;de
pas de d&eacute;cimale.</FONT></FONT></P>
<P STYLE="margin-bottom: 0cm"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>Suite
&agrave; ceci il y a trois possibilit&eacute;s : </FONT></FONT>
</P>
<P STYLE="margin-bottom: 0cm"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>Soit
la prochaine direction demand&eacute;e n'est pas occup&eacute;e par
un mur et par cons&eacute;quent le prochain mouvement est remis &agrave;
&laquo;&nbsp;none&nbsp;&raquo;, puis le Pacman effectue une rotation
vers la position requise avant de s'y engager. </FONT></FONT>
</P>
<P STYLE="margin-bottom: 0cm"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>Soit
la prochaine orientation requise est occup&eacute;e par un mur et la
prochaine case dans la direction d&eacute;j&agrave; entam&eacute;e
est libre dans ce cas le Pacman continue d'avancer (d&eacute;placement
de 0,2 en X ou en Z par frame)</FONT></FONT></P>
<P STYLE="margin-bottom: 0cm"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>Soit
aucun d&eacute;placement n'est disponible et le Pacman s'arr&ecirc;te.</FONT></FONT></P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<P STYLE="margin-bottom: 0cm"><FONT FACE="Times New Roman, serif"><FONT SIZE=3><U>Fant&ocirc;mes
:</U></FONT></FONT></P>
<P STYLE="margin-bottom: 0cm">La gestion des d&eacute;placements des
fant&ocirc;mes se fait d'une mani&egrave;re un peu similaire &agrave;
celle de Pacman &agrave; ceci pr&egrave;s que ce ne sont pas une
seule future direction qui est enregistr&eacute;e mais quatre.</P>
<P STYLE="margin-bottom: 0cm">En effet avant de d&eacute;placer un
fant&ocirc;me, ces quatre prochaines directions sont calcul&eacute;es
en fonction du comportement qu'il doit employer &agrave; chaque fois
qu'il se retrouve au milieu d'une case.</P>
<P STYLE="margin-bottom: 0cm">En fonction de cela le m&ecirc;me
algorithme que pr&eacute;c&eacute;demment se d&eacute;clenche &agrave;
la diff&eacute;rence que si la position demand&eacute;e num&eacute;ro
une n'est pas disponible alors on tente avec la num&eacute;ro deux
puis la trois pour finir avec la quatre qui sera toujours la marche
arri&egrave;re (cas ne pouvant pas arriver si on poss&egrave;de une
carte ne comportant pas d'impasse).</P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<P STYLE="margin-bottom: 0cm"><FONT SIZE=4><U><B>Gestion des
collisions</B></U></FONT></P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<P STYLE="margin-bottom: 0cm">Il y a trois styles de collisions
possible : la collision entre Pacman et les boules jaunes ou rouges,
les collisions entre les bonhommes et les murs qui sont &eacute;vit&eacute;es
lors du d&eacute;placement des personnages et les collisions entre
Pacman et les fant&ocirc;mes qui peuvent avoir plusieurs effets
diff&eacute;rents.</P>
<P STYLE="margin-bottom: 0cm">Chaque collision se g&egrave;re de
mani&egrave;re s&eacute;par&eacute;e dans sa propre fonction dans la
classe Scene.</P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<P STYLE="margin-bottom: 0cm"><U>Pacman / Collectable (</U><FONT COLOR="#0000ff"><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I><U>void</U></I></FONT></FONT></FONT><U>
</U><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I><U>colisionManagement()</U></I></FONT></FONT><FONT FACE="Consolas"><FONT SIZE=2 STYLE="font-size: 9pt"><U>)</U></FONT></FONT></P>
<P STYLE="margin-bottom: 0cm">A chaque fois que le Pacman se retrouve
au milieu d'une case ( position en X et en Z ne comportant pas de
d&eacute;cimale) on v&eacute;rifie que la case sur laquelle elle se
trouve ne contient pas de boule (gr&acirc;ce &agrave; la grille
contenue dans Field).</P>
<P STYLE="margin-bottom: 0cm">Si c'est le cas, une recherche par
dichotomie est effectu&eacute;e sur le vector de Collectable (d'o&ugrave;
le fait d'avoir tri&eacute; le tableau auparavant) et une suppression
de l'&eacute;l&eacute;ment cibl&eacute; &eacute;vite qu'il soit
r&eacute;affich&eacute; dans le futur.</P>
<P STYLE="margin-bottom: 0cm">La grille de Field est elle aussi mis &agrave;
jour afin que la collision ne soit plus prise en compte.</P>
<P STYLE="margin-bottom: 0cm">Dans le cas o&ugrave; l'objet collect&eacute;
&eacute;tait une Ball alors le score est incr&eacute;ment&eacute; de
dix points. 
</P>
<P STYLE="margin-bottom: 0cm">Si c'&eacute;tait une instance de
Destructor alors un compteur &laquo;&nbsp;eaterCounter&nbsp;&raquo;
se met en marche pour une dur&eacute;e de huit secondes.</P>
<P STYLE="margin-bottom: 0cm">Ce compteur est utile pour g&eacute;rer
le comportement des fant&ocirc;mes mais aussi pour indiquer de quelle
mani&egrave;re le logiciel va r&eacute;agir dans le cas d'une
collision Pacman/Ghost.</P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<P STYLE="margin-bottom: 0cm"><U>Pacman/Ghos</U>t (bool
colisionPacmanGhost())</P>
<P STYLE="margin-bottom: 0cm">Les cas de collision entre Pacman et
chaque fant&ocirc;mes sont g&eacute;r&eacute;es gr&acirc;ce &agrave;
un calcul math&eacute;matique simple :</P>
<P STYLE="margin-bottom: 0cm">si la distance entre le centre de
chaque personnage est inf&eacute;rieure &agrave; la somme de la
moiti&eacute; des largeurs des deux bonhommes alors la collision est
d&eacute;tect&eacute;e.</P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<P STYLE="margin-bottom: 0cm">Nous avons d&egrave;s lors deux cas
possible :</P>
<P STYLE="margin-bottom: 0cm">Soit le &laquo;&nbsp;eaterCounter&nbsp;&raquo;
est sup&eacute;rieur &agrave; z&eacute;ro ce qui a pour effet de
changer de comportement du fant&ocirc;me en &laquo;DEAD&raquo; et
d'augmenter le score de 200 points.</P>
<P STYLE="margin-bottom: 0cm">Soit le &laquo;&nbsp;eaterCounter&nbsp;&raquo;
est n&eacute;gatif et le fant&ocirc;me n'est pas mort donc la
fonction renvoi True pour signaler que le Pacman vient de perdre une
vie.</P>
<P STYLE="margin-bottom: 0cm">Dans tout les autres cas la m&eacute;thode
renvoi False.</P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<P STYLE="margin-bottom: 0cm"><FONT SIZE=4><U><B>Comportement des
fant&ocirc;mes</B></U></FONT></P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<P STYLE="margin-bottom: 0cm">Un fant&ocirc;me poss&egrave;de
plusieurs types de comportement qui varient en fonction de l'&eacute;tat
de la partie et qui lui dicte ses futurs d&eacute;placements.</P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<P STYLE="margin-bottom: 0cm">- Le comportement &laquo; NORMAL &raquo;
d&eacute;signe l'ensemble des r&eacute;actions standards d'un
fant&ocirc;me.</P>
<P STYLE="margin-bottom: 0cm">Dans cet &eacute;tat l&agrave; trois
attitudes sont possibles : une r&eacute;action agressive, une
compl&egrave;tement li&eacute;e au hasard et une qui r&eacute;alise
l'extraction de la zone de repopulation.</P>
<P STYLE="margin-bottom: 0cm">Le choix de la r&eacute;action est
d&eacute;termin&eacute;e par sa position sur la carte ou la distance
entre Pacman et le fant&ocirc;me : si le fant&ocirc;me se trouve &agrave;
une distance inf&eacute;rieure &agrave; 15 alors il va adopter une
posture agressive.</P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<P STYLE="margin-bottom: 0cm">Lorsque un fant&ocirc;me essai
d'attaquer Pacman il observe quel est la distance la plus courte
entre X et Z, puis il tente de se diriger vers cette direction.</P>
<P STYLE="margin-bottom: 0cm">Dans le cas o&ugrave; il serait
impossible d'aller dans la direction ou la distance est minimale
alors il tente l'autre direction .</P>
<P STYLE="margin-bottom: 0cm">Si toutefois aucun de ces deux cas
n'est possible il passe en d&eacute;placement hasardeux.</P>
<P STYLE="margin-bottom: 0cm">Nous tenons &agrave; pr&eacute;ciser
que ce comportement n'est pas optimal car certaines incoh&eacute;rences
peuvent s'observer dans le d&eacute;placement.</P>
<P STYLE="margin-bottom: 0cm">La solution optimale aurait &eacute;t&eacute;
d'impl&eacute;menter l'algorithme du plus court chemin de Dijkstra
qui donne un r&eacute;sultat optimal en une complexit&eacute;
relativement basse ( n . log(n) ).</P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<P STYLE="margin-bottom: 0cm">Le d&eacute;placement hasardeux se
contente lui de remplir de mani&egrave;re compl&egrave;tement
al&eacute;atoire les trois premiers prochains d&eacute;placements de
la classe Ghost gr&acirc;ce notamment &agrave; la m&eacute;thode
<I>rand( )</I>.</P>
<P STYLE="margin-bottom: 0cm">Le dernier d&eacute;placement &eacute;tant
lui toujours la direction inverse &agrave; celle d'o&ugrave; l'on
provient (il est donc proscrit de faire marche arri&egrave;re).</P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<P STYLE="margin-bottom: 0cm">Dans le cas o&ugrave; notre fant&ocirc;me
serait pr&eacute;sent dans la zone de repopulation la m&eacute;thode
<FONT COLOR="#0000ff"><I>int</I></FONT> <I>getOutMode()</I> se
d&eacute;clenche.</P>
<P STYLE="margin-bottom: 0cm">Cette fonction s'effectue de la m&ecirc;me
mani&egrave;re que la m&eacute;thode qui g&egrave;re le comportement
agressif.</P>
<P STYLE="margin-bottom: 0cm">La principale diff&eacute;rence est
qu'&agrave; la place de se diriger vers Pacman, on se d&eacute;place
en direction de la sortie de la zone de repopulation. (param&egrave;tre
qui est d&eacute;fini dans Field)</P>
<P STYLE="margin-bottom: 0cm">Cette m&eacute;thode permet notamment
de pouvoir traverser les murs invisibles (TwistedWall) en cas de
besoin.</P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<P STYLE="margin-bottom: 0cm">Le comportement &laquo;&nbsp;RUNAWAY&nbsp;&raquo;
se d&eacute;clenche dans le cas o&ugrave; le compteur
&laquo;&nbsp;eaterCounter&nbsp;&raquo; pr&eacute;sent dans Scene
serait sup&eacute;rieur &agrave; z&eacute;ro.</P>
<P STYLE="margin-bottom: 0cm">Ce comportement est quasi-identique &agrave;
&laquo;&nbsp;NORMAL&nbsp;&raquo; &agrave; ceci pr&ecirc;t que les
fant&ocirc;mes ne peuvent pas adopter de comportement agressif.</P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<P STYLE="margin-bottom: 0cm">Le dernier comportement &laquo;&nbsp;DEAD&nbsp;&raquo;
repr&eacute;sente la r&eacute;action des fant&ocirc;mes lorsque
qu'ils ont &eacute;t&eacute; mang&eacute;s par notre Pacman.</P>
<P STYLE="margin-bottom: 0cm">Au cours de ce comportement le fant&ocirc;me
se contente juste de rentrer au point de repopulation afin de pouvoir
repasser en comportement &laquo;&nbsp;NORMAL&nbsp;&raquo;.</P>
<P STYLE="margin-bottom: 0cm">Pour ce faire on utilise la m&eacute;thode
<FONT COLOR="#0000ff"><I>int</I></FONT> <I>returnMode ( )</I> qui se
sert du m&ecirc;me principe que <FONT COLOR="#0000ff"><I>int</I></FONT>
<I>getOutMode( )</I> ou <FONT COLOR="#0000ff"><I>int</I></FONT>
<I>followMode ( )</I> mais ce coup ci en ciblant le point de repop.</P>
<P STYLE="margin-bottom: 0cm">Si le <I>returnMode()</I> renvoie
&laquo;&nbsp;none&nbsp;&raquo; alors le mode de d&eacute;placement
hasardeux est employ&eacute;.</P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<P STYLE="margin-bottom: 0cm">N&eacute;anmoins les diff&eacute;rents
comportements ne servent pas uniquement &agrave; d&eacute;terminer le
futur d&eacute;placement des fant&ocirc;mes, il est aussi employ&eacute;
pour d&eacute;finir quelle apparence on va donner &agrave; notre
fant&ocirc;me.</P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<P STYLE="margin-bottom: 0cm"><FONT SIZE=4><U><B>Affichage</B></U></FONT></P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<P STYLE="margin-bottom: 0cm">Lorsque nous avons cr&eacute;&eacute;
et affich&eacute; notre plateau, nous nous sommes rendu compte que
l'application ralentissait consid&eacute;rablement en fonction du
nombre d'&eacute;l&eacute;ments pr&eacute;sents, nuisant ainsi aux
performances et &agrave; la fluidit&eacute; du jeu.</P>
<P STYLE="margin-bottom: 0cm">Nous avons alors recherch&eacute; un
moyen de pallier ce probl&egrave;me.</P>
<P STYLE="margin-bottom: 0cm">Notre solution aura &eacute;t&eacute;
d'utiliser une &quot;display list&quot; qui permet de stocker une
liste de commandes OpenGL qui sera pr&eacute;-compil&eacute;e pour
une ex&eacute;cution ult&eacute;rieure.</P>
<P STYLE="margin-bottom: 0cm">Une fois instanci&eacute;e, elle peut
&ecirc;tre appel&eacute;e autant de fois que souhait&eacute;e, sans
consommer de ressources suppl&eacute;mentaires. 
</P>
<P STYLE="margin-bottom: 0cm">Elle a toutefois son inconv&eacute;nient
: une fois compil&eacute;e, cette &quot;display list&quot; ne peut
plus &ecirc;tre modifi&eacute;e.</P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<P STYLE="margin-bottom: 0cm">Dans notre programme, nous avons
utilis&eacute; cet outil pour la cr&eacute;ation des &quot;pac-gommes&quot;,
des fant&ocirc;mes, des cylindres et des quarts de tore composant les
murs.</P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<P STYLE="margin-bottom: 0cm">Ces cr&eacute;ations s'effectuent dans
la fonction <I>init()</I> de notre Main.</P>
<P STYLE="margin-bottom: 0cm">Elle fait alors appel aux autres
fonctions <I>init()</I> pr&eacute;sentes dans d'autres classes.</P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<P STYLE="margin-bottom: 0cm">Lorsque nous avons voulu ajout&eacute;
de la texture &agrave; certains &eacute;l&eacute;ments, il nous
fallait initialiser un ensemble d'appels de fonction permettant
l'application d'une texture &agrave; un &eacute;l&eacute;ment donn&eacute;.</P>
<P STYLE="margin-bottom: 0cm">La fonction <I>init() </I><SPAN STYLE="font-style: normal">nous
a ainsi &eacute;galement servie dans ce but.</SPAN></P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<P STYLE="margin-bottom: 0cm">Les m&eacute;thodes display :</P>
<P STYLE="margin-bottom: 0cm">- Dans la classse Field</P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<P STYLE="margin-bottom: 0cm">Nous avons choisi d'afficher une
texture pour repr&eacute;senter le terrain de mani&egrave;re plus
plaisante.</P>
<P STYLE="margin-bottom: 0cm">Elle consiste en un pav&eacute; sur
lequel sont dispos&eacute;s tout les &eacute;l&eacute;ments du jeu.</P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<P STYLE="margin-bottom: 0cm">- Dans la classe Wall</P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<P STYLE="margin-bottom: 0cm">La cr&eacute;ation de chaque bloc de
mur d&eacute;pend de plusieurs param&egrave;tres : son nombre de
faces partag&eacute; avec d'autres murs, et son angle, permettant de
connaitre l'orientation du mur. 
</P>
<P STYLE="margin-bottom: 0cm">Une fois ces param&egrave;tres d&eacute;finis,
il suffit d'impl&eacute;menter le mur correspondant &agrave; chaque
situation.</P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<P STYLE="margin-bottom: 0cm">- Dans la classe Ghost</P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<P STYLE="margin-bottom: 0cm">La forme et la couleur des fant&ocirc;mes
d&eacute;pendent directement des param&egrave;tres courants du jeu :
Ainsi, si le fant&ocirc;me est dans son &eacute;tat normal,
&quot;vuln&eacute;rable&quot; ou &quot;mort&quot;, un appel de
fonctions diff&eacute;rent sera effectu&eacute;.</P>
<P STYLE="margin-bottom: 0cm">Le fant&ocirc;me est simplement
constitu&eacute; d'une sph&egrave;re dans un cylindre, agr&eacute;ment&eacute;
d'yeux.</P>
<P STYLE="margin-bottom: 0cm">Lorsqu'il est vuln&eacute;rable, il
change de couleur&nbsp;: nous avons essay&eacute; d'appliquer une
texture au cylindre repr&eacute;sentant le fant&ocirc;me dans cet
&eacute;tat, tentative qui s'est r&eacute;v&eacute;l&eacute;e
finalement infructueuse.</P>
<P STYLE="margin-bottom: 0cm">Lorsqu'il est &quot;mort&quot;, seuls
ses yeux demeurent.</P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<P STYLE="margin-bottom: 0cm"><FONT SIZE=4><U><B>Gestion de la camera</B></U></FONT></P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<P STYLE="margin-bottom: 0cm">La particularit&eacute; de ce Pacman 3D
c'est qu'au del&agrave; de son cot&eacute; novateur due notamment &agrave;
la 3D, il propose plusieurs approches de gameplay diff&eacute;rentes.</P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<P STYLE="margin-bottom: 0cm">La fen&ecirc;tre num&eacute;ro une
propose un Pacman assez classique gr&acirc;ce notamment &agrave; une
camera externe ce qui nous permet de voir la sc&egrave;ne sou<FONT FACE="Times New Roman, serif"><FONT SIZE=3>s
tout ses angles possibles (sauf de voir la sc&egrave;ne de dessous).</FONT></FONT></P>
<P STYLE="margin-bottom: 0cm"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>Il
nous est notamment permis de faire tourner la camera autour de la
sc&egrave;ne mais aussi de zoomer et de d&eacute;zoomer &agrave; sa
convenance.</FONT></FONT></P>
<P STYLE="margin-bottom: 0cm"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>Pour
r&eacute;aliser ces manipulations de la camera, nous avons manipul&eacute;
la sc&egrave;ne dans sa globalit&eacute; :</FONT></FONT></P>
<P STYLE="margin-bottom: 0cm"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>pour
calculer l'angle de rotation de la sc&egrave;ne ou le pourcentage de
zoom nous nous somme servi de deux fonctions propos&eacute;e par GLUT
qui sont <I>glutMouseFunc (processMouse)</I> ainsi que <I>glutMotionFunc
(myMousePosition)</I></FONT></FONT></P>
<P STYLE="margin-bottom: 0cm"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>processMouse
est d&eacute;clench&eacute; lorsqu'un utilisateur effectue un clic
avec la sourie.</FONT></FONT></P>
<P STYLE="margin-bottom: 0cm"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>D&egrave;s
lors que le bouton gauche est appuy&eacute; les coordonn&eacute;es du
pointeur de la sourie sont enregistr&eacute;es dans Scene.</FONT></FONT></P>
<P STYLE="margin-bottom: 0cm"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>Puis,
tant que le bouton reste appuy&eacute; les coordonn&eacute;es du
pointeur sont enregistr&eacute;es dans une autre variable de la
classe Scene.</FONT></FONT></P>
<P STYLE="margin-bottom: 0cm"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>Gr&acirc;ce
&agrave; ces coordonn&eacute;es on peut calculer le nouvel angle par
rapport &agrave; X et Y : </FONT></FONT>
</P>
<P STYLE="margin-bottom: 0cm"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>AngleX
+= premierepositionX &ndash; dernierePositionX)/5 (idem pour Y)</FONT></FONT></P>
<P STYLE="margin-bottom: 0cm"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>ainsi
que le nouveau ratio pour le zoom :</FONT></FONT></P>
<P STYLE="margin-bottom: 0cm"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>zoom
+= premierepositionY &ndash; dernierePositionY)/50;</FONT></FONT></P>
<P STYLE="margin-bottom: 0cm"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>Finalement
nous n'avons plus qu'a effectuer deux rotations successives d'angle
AngleX et d'angle AngleY ainsi qu'un glutScalef(zoom,zoom,zoom) pour
avoir notre sc&egrave;ne qui se dessine &agrave; la position voulue.</FONT></FONT></P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<P STYLE="margin-bottom: 0cm"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>La
fen&ecirc;tre num&eacute;ro deux propose quand &agrave; elle un
Pacman avec une vue &agrave; la premi&egrave;re personne ce qui donne
un jeux plus nerveux et d'avantage bas&eacute; sur les r&eacute;flexes
et la chance.</FONT></FONT></P>
<P STYLE="margin-bottom: 0cm"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>La
camera se positionne automatiquement au niveau des yeux du Pacman.</FONT></FONT></P>
<P STYLE="margin-bottom: 0cm"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>Pour
cela c'est la cam&eacute;ra qui est directement manipul&eacute;e
gr&acirc;ce &agrave; l'emploi de </FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>gluLookAt(</I></FONT></FONT></P>
<PRE CLASS="western">  <FONT COLOR="#0000ff"><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>GLdouble</I></FONT></FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I> eyex,  </I></FONT></FONT><FONT COLOR="#0000ff"><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>GLdouble</I></FONT></FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I> eyey,  </I></FONT></FONT><FONT COLOR="#0000ff"><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>GLdouble</I></FONT></FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I> eyez,  </I></FONT></FONT><FONT COLOR="#0000ff"><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>GLdouble</I></FONT></FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I> centerx,  </I></FONT></FONT><FONT COLOR="#0000ff"><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>GLdouble</I></FONT></FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I> centery, </I></FONT></FONT><FONT COLOR="#0000ff"><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>GLdouble</I></FONT></FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I> centerz,  </I></FONT></FONT><FONT COLOR="#0000ff"><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>GLdouble</I></FONT></FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I> upx,  </I></FONT></FONT><FONT COLOR="#0000ff"><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>GLdouble</I></FONT></FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I> upy,  </I></FONT></FONT><FONT COLOR="#0000ff"><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I>GLdouble</I></FONT></FONT></FONT><FONT FACE="Times New Roman, serif"><FONT SIZE=3><I> upz)</I></FONT></FONT>
<FONT FACE="Times New Roman, serif"><FONT SIZE=3>Pour placer correctement la camera &agrave; la place du Pacman on calcule la position du Pacman par rapport &agrave; l'origine du rep&egrave;re en faisant une soustraction ou une addition entre le centre de la sc&egrave;ne et la position du Pacman(ce qui d&eacute;pend de la position du Pacman &agrave; l'instant t).</FONT></FONT></PRE><P STYLE="margin-bottom: 0cm">
<FONT FACE="Times New Roman, serif"><FONT SIZE=3>Pour calculer
l'angle on reprend les m&ecirc;me coordonn&eacute;es trouv&eacute;es
auparavant que l'on remet dans les centerX et centerZ de GluLookAt</FONT></FONT></P>
<P STYLE="margin-bottom: 0cm"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>Puis
on y rajoute un ratio calcul&eacute; pour faire correspondre l'angle
contenu dans la classe Pacman et le centre de l'angle de vision que
l'on cherche &agrave; obtenir.</FONT></FONT></P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
</BODY>
</HTML>